package service;

import model.ClickEvent;

import java.awt.*;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

/**
 * @Author: xwg
 * @CreateDate: 2023/4/9
 */

// 本段代码证明了 异步函数的执行环境并不一定不是声明异步函数的线程(简称声明线程)
// 异步函数只是在时间轴上有极大的不确定性,其不确定性必然来源于CPU切换线程的不确定性,
//    故而如果确定某函数是异步函数,则某函数必定有被送到另一根线程中的经历,但是不一定另一根线程就需要运行该函数,
//    也可能该函数会被再一次送回声明线程,而由声明线程去运行.
//    以js定时任务为例 一个定时任务包含函数体A和定时时间B组成的包裹,
//    这个在页面单线程中使用setTimeOut方法时,被提交给浏览器定时任务专用的公共服务线程配套的事件队列QueueChannel中,
//    该线程取出定时时间B,并且真实完成时间延迟后,把函数体A原封不动的送回js页面的单线程中
public class SpecialPC {

    public static void main(String[] args) {
//        考虑一个问题 ：如果channel需要跟消费者和生产者之间选一个关系走近，应该是谁呢？(答案消费者 化缘钵)
        BlockingQueue<ClickEvent> channelForB = new ArrayBlockingQueue<>(4);
        BlockingQueue<ClickEvent> channelForA = new ArrayBlockingQueue<>(4);
        new Thread(() -> {
            List<String> names = Arrays.asList("div", "button", "li", "span");
            int flag = 1;
            while (true) {
                System.out.println("AAAAAAAAA---begin tick----" + flag);

                double i = Math.floor(Math.random() * names.size());
                String name = names.get((int) i);
                Integer xy = (int) (Math.random() * 100);
                System.out.println("AAAAAAAAA---middle------" + flag + "  生产的事件 ： " + name + "  " + xy);
                Runnable listener = () -> {
                    System.out.println("AAAAAAAA" + " ---当前线程名：" +
                            Thread.currentThread().getName() + " ---事件信息：" + name + "  " + xy);
                };
                ClickEvent clickEvent = new ClickEvent(name, xy, listener);


                try {
                    channelForB.put(clickEvent);
                } catch (InterruptedException ex) {
                    ex.printStackTrace();
                }

                try {
                    ClickEvent e = channelForA.take();
                    e.eventListener.run();
                    System.out.println("AAAAAAAA被打回的旧信息： " + e);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                System.out.println("AAAAAAAAA---end tick-----" + flag);

            }
        }, "A").start();

        new Thread(() -> {
            while (true) {

                System.out.println("BBBBBBB====begin tick=====");

                try {
                    ClickEvent e = channelForB.take();

                    e.eventListener.run();
                    double r = Math.random();
                    System.out.println("BBBBBBB=========随机数 ："+r);
                    if (r > 0.5) {
                        e.target = e.target + "_B";
                        channelForA.put(e);
                    }

                } catch (InterruptedException ex) {
                    ex.printStackTrace();
                }
                System.out.println("BBBBBBB=====begin tick======");
            }
        }, "B").start();
    }
}
